<?php
/**
 * Description: 事业单位提交
 * User: devforma
 * Date: 2016/12/5
 * Time: 10:40
 */
require __DIR__ . '/includes/utils.php';

class SubmitExercise implements iController {
    private $exerciseType = ['entire' => 1, 'error' => 2];

    private $submitQuestions = null;
    private $userId          = 0;
    private $paperId         = 0;
    private $exerciseId      = 0;
    private $duration        = 0;
    private $isDone          = false;
    private $userData        = null;
    private $now             = '';
    private $terminalType    = '';

    /**
     * api请求处理主函数
     * @param array $queryArgs 就是$_REQUEST变量
     * @return array api返回结果，必须含response_code
     */
    public function output($queryArgs) {
        if (validateUser($queryArgs) !== 1 || empty($queryArgs['type']) || !in_array($queryArgs['type'], array_keys($this->exerciseType), true)
            || !isset($queryArgs['done']) || empty($queryArgs['questions']) || !isset($queryArgs['duration'])) {
            return genOutput(1000);
        }

        $this->userId          = (int)$queryArgs['user_id']; //用户id
        $this->isDone          = empty($queryArgs['done']) ? false : true; //练习是否完成
        $this->paperId         = empty($queryArgs['paper_id']) ? 0 : (int)$queryArgs['paper_id']; //试卷id
        $this->duration        = (int)$queryArgs['duration']; //做题总时长
        $this->exerciseId      = empty($queryArgs['exercise_id']) ? 0 : (int)$queryArgs['exercise_id']; //练习id
        $this->submitQuestions = json_decode($queryArgs['questions']); //提交数据
        $this->terminalType    = empty($queryArgs['terminal_type']) ? '' : $queryArgs['terminal_type']; //终端

        if (!$this->submitIsValidate()) {
            return genOutput(1000);
        }

        $this->now = date('Y-m-d H:i:s');
        $this->userData = InstitutionUtils::getUserData($this->userId);

        switch ($queryArgs['type']) {
            case 'entire':
                $this->submitEntireExercise();
                break;

            case 'error':
                $this->submitErrorExercise();
                break;

            default:
                return genOutput(1000);
        }

        //保存单题记录
        $this->saveTest();

        return genOutput(1, ['exercise_type' => $queryArgs['type'], 'exercise_id' => $this->exerciseId]);
    }

    /**
     * 整卷练习处理逻辑
     */
    private function submitEntireExercise() {
        global $uddb;

        //获取答题详细统计
        $summary = $this->getSubmitSummary();

        //更新排名信息
        $evaluate = 0.0; //分数
        InstitutionUtils::updateInstitutionEvaluate($this->paperId, $evaluate);

        /**--------------------------------------------------------------
         * 用户练习数据更新
         *-------------------------------------------------------------*/
        $exercise = [
            'user_id'       => $this->userId,
            'paper_id'      => $this->paperId,
            'paper_type'    => $this->exerciseType['entire'],
            'question_info' => json_encode($this->submitQuestions),
            'action_time'   => $this->now,
            'status'        => $this->isDone ? 1 : 2,
            'duration'      => $this->duration,
            'right_count'   => $summary['right'],
            'total_count'   => $summary['total'],
            'evaluate'      => $evaluate,
            'extra_info'    => json_encode(['notes' => $summary['notes']]),
            'terminal_type' => $this->terminalType
        ];

        if ($this->exerciseId) { //更新记录
            $uddb->update('institution_user_paper', $exercise, ['id' => $this->exerciseId]);
        } else { //插入记录
            $exercise['paper_title'] = InstitutionUtils::getPaperInfo($this->paperId)['name'];
            $uddb->insert('institution_user_paper', $exercise);
            $this->exerciseId = (int)$uddb->lastInsertId();
        }

        /**--------------------------------------------------------------
         * 用户统计数据更新
         *-------------------------------------------------------------*/
        $this->updateUserData($summary);


    }


    /**
     * 错题练习处理逻辑
     */
    private function submitErrorExercise() {
        global $uddb;

        //获取答题详细统计
        $summary = $this->getSubmitSummary();

        /**--------------------------------------------------------------
         * 用户练习数据更新
         *-------------------------------------------------------------*/
        $exercise = [
            'user_id'       => $this->userId,
            'paper_id'      => $this->paperId,
            'paper_type'    => $this->exerciseType['entire'],
            'question_info' => json_encode($this->submitQuestions),
            'action_time'   => $this->now,
            'status'        => $this->isDone ? 1 : 2,
            'duration'      => $this->duration,
            'right_count'   => $summary['right'],
            'total_count'   => $summary['total'],
            'evaluate'      => 0,
            'extra_info'    => json_encode(['notes' => $summary['notes']]),
            'terminal_type' => $this->terminalType
        ];

        if ($this->exerciseId) { //更新记录
            $uddb->update('institution_user_paper', $exercise, ['id' => $this->exerciseId]);
        } else { //插入记录
            $exercise['paper_title'] = InstitutionUtils::getPaperInfo($this->paperId)['name'];
            $uddb->insert('institution_user_paper', $exercise);
            $this->exerciseId = (int)$uddb->lastInsertId();
        }

        /**--------------------------------------------------------------
         * 用户统计数据更新
         *-------------------------------------------------------------*/
        $this->updateUserData($summary);
    }

    /**
     * 更新用户统计数据
     *
     * @param array $summary 知识点统计
     */
    private function updateUserData($summary) {
        $userNotes = json_decode($this->userData['note_info'], true);
        foreach ($summary['notes'] as $noteId => $note) {
            if (isset($userNotes[$noteId])) {
                $userNotes[$noteId][0] += $note['total']; //该知识点下总答题量
                $userNotes[$noteId][1] += $note['right']; //该知识点下正确题量
            }
        }

        $newData = [
            'note_info'       => json_encode($userNotes),
            'total_count'     => $this->userData['total_count'] += $summary['total'],
            'right_count'     => $this->userData['right_count'] += $summary['right'],
            'last_updated_at' => $this->now
        ];
        $newData['accuracy'] = $newData['right_count'] / $newData['total_count'];

        InstitutionUtils::updateUserData($this->userId, $newData);
    }


    /**
     * 保存答题记录
     */
    private function saveTest() {
        global $uddb;

        //构造insert数据
        $values = [];
        foreach ($this->submitQuestions as $q) {
            $values[] = [
                'user_id'      => $this->userId,
                'question_id'  => $q->id,
                'note_id'      => $q->note_id,
                'exercise_id'  => $this->exerciseId,
                'user_answer'  => $q->answer,
                'is_right'     => $q->is_right,
                'test_time'    => $this->now,
                'is_collected' => 0
            ];
        }

        //写表
        $uddb->table('institution_history_user_tests')->batchInsert($values);
    }

    /**
     * 获取答题数据统计
     *
     * @return array
     */
    private function getSubmitSummary() {
        $notes = []; //题目知识点统计
        $total = 0; //总答题数
        $right = 0; //总正确数

        foreach ($this->submitQuestions as $q) {
            if(isset($notes[$q->note_id])) {
                $notes[$q->note_id]['total'] += 1;
                $notes[$q->note_id]['right'] += $q->is_right ? 1 : 0;
                $notes[$q->note_id]['duration'] += $q->duration;
            } else {
                $notes[$q->note_id] = [
                    'total'    => 1,
                    'duration' => $q->duration,
                    'right'    => $q->is_right ? 1 : 0
                ];
            }

            $total += 1;
            $right += $q->is_right ? 1 : 0;
        }

        return [
            'notes' => $notes,
            'total' => $total,
            'right' => $right
        ];
    }

    /**
     * 检测提交有效性
     *
     * @return bool
     */
    private function submitIsValidate() {
        global $uddb;

        //试卷id和练习id均为空
        if (empty($this->paperId) && empty($this->exerciseId)) {
            return false;
        }

        //提交题目信息为空或格式不对
        if (empty($this->submitQuestions) || !is_array($this->submitQuestions)) {
            return false;
        }

        //检查练习是否有效
        if (!empty($this->exerciseId)) {
            $exists = $uddb->getRow('SELECT `id`, `status` FROM `institution_user_paper` WHERE `id`=:eid AND `user_id`=:uid',
                [':eid' => $this->exerciseId, ':uid' => $this->userId]);
            if (empty($exists) || $exists->status == 1) { //没有记录或者记录已经完成
                return false;
            }
        }

        return true;
    }
}